package com.demo.search.engine;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;

import com.demo.search.exception.IndexException;

/**
 * 模型-Document双向转化引擎<p/>
 * 用来对索引-对象相互转换。
 * 
 * @author ryuu.kk
 */
public interface SearchEngine {
	
	// 默认Table在Field中的key(目的是可以区分不同表的检索或创建多表的联合查询)
	static final String PARSER_TABLE = "_TABLE_";

	/**
	 * 是否支持该对象模型创建索引
	 * @param target Object
	 * @return boolean
	 */
	boolean support(Object target);
	
	/**
	 * 将对象模型转化为Fieldable列表
	 * @param obj 对象模型
	 * @return List<Fieldable>
	 */
	List<Fieldable> objectToFields(Object obj);
	
	/**
	 * 将Document转化为模型对象列表
	 * @param docList List<Document>
	 * @param clazz 转化对象类
	 * @return List<T> 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	<T> List<T> documentToTarget(List<Document> docList, Class<T> clazz) throws IllegalArgumentException, IllegalAccessException, InstantiationException;
	
	/**
	 * 将Document转化为模型对象列表
	 * @param docList List<Document>
	 * @param clazz 转化对象类
	 * @return List<T> 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	<T> List<T> documentToTarget(List<Document> docList, Class<T> clazz, int maxLength) throws IllegalArgumentException, IllegalAccessException, InstantiationException;
	
	/**
	 * 将Document转化为模型对象列表
	 * @param docList List<Document>
	 * @param clazz 转化对象类
	 * @param highlighter HighlighterHandler 高亮处理对象
	 * @return List<T> 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	<T> List<T> documentToTarget(List<Document> docList, Class<T> clazz, HighlighterHandler highlighter) 
			throws IllegalArgumentException, IllegalAccessException, InstantiationException;
	
	/**
	 * 将Document转化为模型对象列表
	 * @param docList List<Document>
	 * @param clazz 转化对象类
	 * @param highlighter HighlighterHandler 高亮处理对象
	 * @return List<T> 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	<T> List<T> documentToTarget(List<Document> docList, Class<T> clazz, HighlighterHandler highlighter, int maxLength) 
			throws IllegalArgumentException, IllegalAccessException, InstantiationException;
	
	/**
	 * 创建对象索引
	 * @param indexWriter IndexWriter
	 * @param targetList 对象模型
	 * @param autoCommit 自动提交
	 * @throws IndexException 索引异常
	 */
	<T> void index(List<T> targetList, boolean autoCommit) throws IndexException;

	/**
	 * 创建索引
	 * @param fieldList List<Fieldable>
	 * @throws IOException
	 */
	void createIndex(List<Fieldable> fieldList) throws IOException;
	
	/**
	 * 创建索引
	 * @param target 模型目标对象
	 * @throws IOException
	 */
	void createIndex(Object target) throws IOException;
	
	/**
	 * 文件进入索引
	 * @param br 文本流
	 * @param split 分隔符
	 * @param name Field的name
	 * @param store Store
	 * @param index Index
	 * @return int 索引创建条数
	 * @throws IOException
	 */
	int createIndex(BufferedReader br, String split, String[] name, Store[] store, Index[] index) throws IOException;

	/**
	 * 创建单条索引
	 * @param name Field的name
	 * @param value Field的value
	 * @param store Store
	 * @param index Index
	 * @param autoCommit 自动提交
	 * @throws IOException
	 */
	void createIndex(String name, String value, Store store, Index index, boolean autoCommit) throws IOException;

	/**
	 * 更新索引
	 * @param objList 目标对象
	 * @throws IndexException 索引异常
	 */
	void updateIndexList(List<Object> objList) throws IndexException;

	/**
	 * 对单模型进行索引
	 * @param target 目标对象
	 * @throws IndexException
	 */
	void updateIndex(Object target) throws IndexException;
	
	/**
	 * 对单模型进行索引
	 * @param id id主键
	 * @param target 目标对象
	 * @throws IndexException;
	 */
	void updateIndex(Long id, Object target) throws IndexException;

	/**
	 * 更新索引
	 * @param term
	 * @param fieldList
	 * @throws IndexException
	 */
	void updateIndex(Term term, List<Fieldable> fieldList) throws IndexException;

	/**
	 * 删除索引
	 * @param key 索引key
	 * @param value 索引value
	 * @throws IndexException
	 */
	void deleteIndex(String key, String value) throws IndexException;

	/**
	 * 删除索引
	 * @param target 目标模型
	 * @throws IndexException
	 */
	void deleteIndex(Object target) throws IndexException;
	
	/**
	 * 批量删除
	 * @param objList 目标对象列表
	 */
	void deleteIndexList(List<Object> objList);

	/**
	 * 删除所有索引
	 */
	void deleteAll();

	/**
	 * 获得当前IndexWriter
	 * @return IndexWriter
	 */
	IndexWriter ownerIndexWriter();

}
